package com.blockchain.front.service.security.achieve;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.UnixCrypt;

import com.blockchain.common.enums.BankCardStatus;
import com.blockchain.common.enums.IsPass;
import com.blockchain.common.enums.JymmType;
import com.blockchain.common.enums.ZrState;
import com.blockchain.common.enums.ZrType;
import com.blockchain.framework.http.upload.PartFile;
import com.blockchain.framework.service.ServiceFactory;
import com.blockchain.framework.service.ServiceResource;
import com.blockchain.framework.service.exception.ParameterException;
import com.blockchain.framework.service.query.ArrayParser;
import com.blockchain.front.config.FrontConst;
import com.blockchain.front.service.security.SecurityManage;
import com.blockchain.front.service.security.entity.BankCard;
import com.blockchain.front.service.security.entity.BankEntity;
import com.blockchain.front.service.security.entity.QbdzEntity;
import com.blockchain.front.util.MD5;
import com.blockchain.front.util.SendMsg;
import com.blockchain.util.StringHelper;
import com.blockchain.util.parser.EnumParser;
import com.blockchain.variables.P2PConst;
import com.ucpaas.sms.client.AbsRestClient;

public class SecurityManageImpl extends AbstractSecurityService implements SecurityManage {

	public static class SecurityManageFactory implements ServiceFactory<SecurityManage> {

		@Override
		public SecurityManage newInstance(ServiceResource serviceResource) {
			return new SecurityManageImpl(serviceResource);
		}
	}

	public SecurityManageImpl(ServiceResource serviceResource) {
		super(serviceResource);
	}

	@Override
	public void updateLogin(String oldpassword, String newpassword, String repassword) throws Throwable {
		if (StringHelper.isEmpty(oldpassword)) {
			throw new ParameterException("err_1049");
		}
		if (StringHelper.isEmpty(newpassword)) {
			throw new ParameterException("err_1050");
		}
		if (!newpassword.equals(repassword)) {
			throw new ParameterException("err_1051");
		}
		String _ymm = selectString(P2PConst.DB_USER, "SELECT F03 FROM T6010 WHERE F01=?",
				serviceResource.getSession().getAccountId());
		String _jymm = selectString(P2PConst.DB_USER, "SELECT F11 FROM T6011 WHERE F01=?",
				serviceResource.getSession().getAccountId());
		if (!UnixCrypt.crypt(oldpassword, DigestUtils.sha256Hex(oldpassword)).equals(_ymm)) {
			throw new ParameterException("err_1052");
		}
		
		if (!StringHelper.isEmpty(_jymm)&& _jymm.equals(UnixCrypt.crypt(newpassword, DigestUtils.sha256Hex(newpassword)))) {
			throw new ParameterException("err_1053");
		}
		if (!StringHelper.isEmpty(_jymm)&& _jymm.equals(MD5.getMd5Value(newpassword))) {
			throw new ParameterException("err_1002");
		}
		execute(getConnection(P2PConst.DB_USER), "UPDATE T6010 SET F03=? WHERE F01=?",
				UnixCrypt.crypt(newpassword, DigestUtils.sha256Hex(newpassword)),
				serviceResource.getSession().getAccountId());
		// 发送短信
		sms(serviceResource.getSession().getAccountId());
	}

	@Override
	public void updateJymm(String oldpassword, String newpassword, String repassword) throws Throwable {
		if (StringHelper.isEmpty(oldpassword)) {
			throw new ParameterException("err_1049");
		}
		if (StringHelper.isEmpty(newpassword)) {
			throw new ParameterException("err_1050");
		}
		if (!newpassword.equals(repassword)) {
			throw new ParameterException("err_1051");
		}
		String _dlmm = selectString(P2PConst.DB_USER, "SELECT F03 FROM T6010 WHERE F01=?",
				serviceResource.getSession().getAccountId());
		String _ymm = selectString(P2PConst.DB_USER, "SELECT F11 FROM T6011 WHERE F01=?",
				serviceResource.getSession().getAccountId());
		
		if (!StringHelper.isEmpty(_dlmm)&& _dlmm.equals(UnixCrypt.crypt(newpassword, DigestUtils.sha256Hex(newpassword)))) {
			throw new ParameterException("err_1002");
		}
		String md5password = MD5.getMd5Value(oldpassword);
		if (md5password.equals(_ymm)) {
			execute(getConnection(FrontConst.DB_USER), "UPDATE T6011 SET F11=? WHERE F01=?",
					UnixCrypt.crypt(newpassword, DigestUtils.sha256Hex(newpassword)),
					serviceResource.getSession().getAccountId());
		} else {
			if (!UnixCrypt.crypt(oldpassword, DigestUtils.sha256Hex(oldpassword)).equals(_ymm)) {
				throw new ParameterException("err_1052");
			}
			execute(getConnection(P2PConst.DB_USER), "UPDATE T6011 SET F11=? WHERE F01=?",
					UnixCrypt.crypt(newpassword, DigestUtils.sha256Hex(newpassword)),
					serviceResource.getSession().getAccountId());
			sms(serviceResource.getSession().getAccountId());
		}
		
		
		
	}

	/**
	 * 发送短信 2017年8月1日13:47:20
	 * 
	 * @throws IOException
	 */
	private void sms(int userid) throws SQLException, IOException {
		if (userid > 0) {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
			String iphone = selectString(P2PConst.DB_USER, "SELECT F02 FROM T6010 WHERE F01=?", userid);// 发送短信
			StringBuilder param = new StringBuilder();
			param.append(StringHelper.truncation(iphone)).append(",")
				 .append(df.format(new Date())).append(",")
				 .append("BTB");
			
			SendMsg.sendMsg(AbsRestClient.getValueByKey("N_SMS_XJMM"),param.toString(),iphone);	
		}
	}

	@Override
	public void jymmSz(JymmType tpwdsetting, String paypassword) throws Throwable {
		if (tpwdsetting == null) {
			throw new ParameterException("err_1053");
		}
		if (StringHelper.isEmpty(paypassword)) {
			throw new ParameterException("err_1036");
		}
		if (!Jymm(paypassword)) {
			throw new ParameterException("err_1029");
		}
		execute(getConnection(P2PConst.DB_USER), "UPDATE T6011 SET F12=? WHERE F01=?", tpwdsetting,
				serviceResource.getSession().getAccountId());
	}

	@Override
	public JymmType getjymmSz() throws Throwable {
		return EnumParser.parse(JymmType.class, selectString(P2PConst.DB_USER, "SELECT F12 FROM T6011 WHERE F01=?",
				serviceResource.getSession().getAccountId()));
	}

	private boolean Jymm(String jymm) throws Throwable {
		String _ymm = selectString(P2PConst.DB_USER, "SELECT F11 FROM T6011 WHERE F01=?",
				serviceResource.getSession().getAccountId());
		String md5password = MD5.getMd5Value(jymm);
		if (md5password.equals(_ymm)) {
			execute(getConnection(FrontConst.DB_USER), "UPDATE T6011 SET F11=? WHERE F01=?",
					UnixCrypt.crypt(jymm, DigestUtils.sha256Hex(jymm)), serviceResource.getSession().getAccountId());
		} else {
			if (!UnixCrypt.crypt(jymm, DigestUtils.sha256Hex(jymm)).equals(_ymm)) {
				return false;
			}
		}
		return true;
	}

	@Override
	public BankEntity[] getBank() throws Throwable {
		return selectAll(getConnection(P2PConst.DB_USER), new ArrayParser<BankEntity>() {
			ArrayList<BankEntity> list = new ArrayList<>();

			@Override
			public BankEntity[] parse(ResultSet re) throws SQLException {
				while (re.next()) {
					BankEntity b = new BankEntity();
					b.id = re.getInt(1);
					b.name = re.getString(2);
					list.add(b);
				}
				return list == null || list.size() == 0 ? null : list.toArray(new BankEntity[list.size()]);
			}
		}, "SELECT F01,F02 FROM T6052 ORDER BY F01 DESC");

	}

	@Override
	public void addBank(String bq, int yhid, String sheng, String shi, String khzh, String kh, String jymm)
			throws Throwable {
		if (yhid <= 0) {
			throw new ParameterException("err_1054");
		}
		if (StringHelper.isEmpty(sheng)) {
			throw new ParameterException("err_1055");
		}
		if (StringHelper.isEmpty(shi)) {
			throw new ParameterException("err_1056");
		}
		if (StringHelper.isEmpty(khzh)) {
			throw new ParameterException("err_1057");
		}
		if (StringHelper.isEmpty(kh)) {
			throw new ParameterException("err_1058");
		}
		if (!Jymm(jymm)) {
			throw new ParameterException("err_1029");
		}
		int i = selectInt(P2PConst.DB_USER, "SELECT COUNT(F01) FROM T6024 WHERE F02<>? AND F06=?",
				serviceResource.getSession().getAccountId(), kh);
		if (i > 0) {
			throw new ParameterException("err_1059");
		}
		int id = selectInt(P2PConst.DB_USER, "SELECT F01 FROM T6024 WHERE F02=? AND F06=? AND F07=?",
				serviceResource.getSession().getAccountId(), kh, BankCardStatus.SC);
		if (id > 0) {
			execute(getConnection(P2PConst.DB_USER), "UPDATE T6024 SET F07=?,F08=CURRENT_TIMESTAMP() WHERE F01=?",
					BankCardStatus.QY, id);
		} else {
			execute(getConnection(P2PConst.DB_USER),
					"INSERT INTO T6024 SET F02=?,F03=?,F04=?,F05=?,F06=?,F08=CURRENT_TIMESTAMP(),F09=?,F10=? ",
					serviceResource.getSession().getAccountId(), yhid, sheng, khzh, kh, shi, bq);
		}

	}

	/**
	 * 校验银行卡卡号
	 * 
	 * @param cardId
	 * @return
	 */
	protected boolean checkBankCard(String cardId) {
		if (cardId.trim().length() < 16) {
			return false;
		}
		char bit = getBankCardCheckCode(cardId.substring(0, cardId.length() - 1));
		if (bit == 'N') {
			return false;
		}
		return cardId.charAt(cardId.length() - 1) == bit;
	}

	protected char getBankCardCheckCode(String nonCheckCodeCardId) {
		if (nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0
				|| !nonCheckCodeCardId.matches("\\d+")) {
			// 如果传的不是数据返回N
			return 'N';
		}
		char[] chs = nonCheckCodeCardId.trim().toCharArray();
		int luhmSum = 0;
		for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
			int k = chs[i] - '0';
			if (j % 2 == 0) {
				k *= 2;
				k = k / 10 + k % 10;
			}
			luhmSum += k;
		}
		return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
	}

	@Override
	public BankCard[] bankList() throws Throwable {
		return selectAll(getConnection(P2PConst.DB_USER), new ArrayParser<BankCard>() {
			ArrayList<BankCard> list = new ArrayList<BankCard>();

			@Override
			public BankCard[] parse(ResultSet re) throws SQLException {
				while (re.next()) {
					BankCard b = new BankCard();
					b.id = re.getInt(1);
					b.yh = re.getString(2);
					b.sheng = re.getString(3);
					b.khzh = re.getString(4);
					b.kh = re.getString(5);
					b.sj = re.getTimestamp(6);
					b.shi = re.getString(7);
					b.bq = re.getString(8);
					list.add(b);
				}
				return list == null || list.size() == 0 ? null : list.toArray(new BankCard[list.size()]);
			}
		}, "SELECT T6024.F01,T6052.F02 khyh,T6024.F04,T6024.F05,T6024.F06,T6024.F08,T6024.F09,T6024.F10 FROM T6024 LEFT JOIN T6052 ON T6024.F03=T6052.F01 WHERE T6024.F07=? AND T6024.F02=? ORDER BY T6024.F08 DESC",
				BankCardStatus.QY, serviceResource.getSession().getAccountId());
	}

	@Override
	public void deleteBank(int id) throws Throwable {
		if (id <= 0) {
			throw new ParameterException("err_1060");
		}
		execute(getConnection(P2PConst.DB_USER), "UPDATE T6024 SET F07=? WHERE F01=?", BankCardStatus.SC, id);
	}

	@Override
	public QbdzEntity[] getXlbxx() throws Throwable {
		return selectAll(getConnection(P2PConst.DB_USER), new ArrayParser<QbdzEntity>() {
			ArrayList<QbdzEntity> list = new ArrayList<QbdzEntity>();

			@Override
			public QbdzEntity[] parse(ResultSet re) throws SQLException {
				while (re.next()) {
					QbdzEntity x = new QbdzEntity();
					x.id = re.getInt(1);
					x.ywjc = re.getString(2);
					x.zwm = re.getString(3);
					x.tblj = re.getString(4);
					x.zwm_f = re.getString(5);
					if (list == null) {
						list = new ArrayList<>();
					}
					list.add(x);
				}
				return list == null ? null : list.toArray(new QbdzEntity[list.size()]);
			}
		}, "SELECT F01,F03,F04,F05,F28 FROM T6013 WHERE F01>0 ORDER BY F01 ASC ");

	}

	@Override
	public QbdzEntity[] getZrXlbxx() throws Throwable {
		return selectAll(getConnection(P2PConst.DB_USER), new ArrayParser<QbdzEntity>() {
			ArrayList<QbdzEntity> list = new ArrayList<QbdzEntity>();

			@Override
			public QbdzEntity[] parse(ResultSet re) throws SQLException {
				while (re.next()) {
					QbdzEntity x = new QbdzEntity();
					x.id = re.getInt(1);
					x.ywjc = re.getString(2);
					x.zwm = re.getString(3);
					x.tblj = re.getString(4);
					x.zwm_f = re.getString(5);
					if (list == null) {
						list = new ArrayList<>();
					}
					list.add(x);
				}
				return list == null ? null : list.toArray(new QbdzEntity[list.size()]);
			}
		}, "SELECT F01,F03,F04,F05,F28 FROM T6013 WHERE F01>0 AND F06!=? ORDER BY F01 ASC ", ZrState.F);

	}

	@Override
	public QbdzEntity[] getZcXlbxx() throws Throwable {
		return selectAll(getConnection(P2PConst.DB_USER), new ArrayParser<QbdzEntity>() {
			ArrayList<QbdzEntity> list = new ArrayList<QbdzEntity>();

			@Override
			public QbdzEntity[] parse(ResultSet re) throws SQLException {
				while (re.next()) {
					QbdzEntity x = new QbdzEntity();
					x.id = re.getInt(1);
					x.ywjc = re.getString(2);
					x.zwm = re.getString(3);
					x.tblj = re.getString(4);
					if (list == null) {
						list = new ArrayList<>();
					}
					list.add(x);
				}
				return list == null ? null : list.toArray(new QbdzEntity[list.size()]);
			}
		}, "SELECT F01,F03,F04,F05 FROM T6013 WHERE F01>0 AND F07=? ORDER BY F01 ASC ", IsPass.S);

	}

	@Override
	public QbdzEntity[] getXlb() throws Throwable {
		StringBuffer sql = new StringBuffer("SELECT mc.F01,mc.F05,");
		sql.append(" mr.F03 ywm_c,mr.F04 zwm_c, mc.F03 ywm_r,mc.F04 zwm_r,T6015.F01");
		sql.append("  FROM T6015 LEFT JOIN T6013 mr ON mr.F01=T6015.F03 ");
		sql.append("  LEFT JOIN T6013 mc ON mc.F01=T6015.F04 ");
		sql.append("  WHERE mc.F01>0  ORDER BY mc.F01 ASC");

		return selectAll(getConnection(P2PConst.DB_USER), new ArrayParser<QbdzEntity>() {
			ArrayList<QbdzEntity> list = new ArrayList<QbdzEntity>();

			@Override
			public QbdzEntity[] parse(ResultSet re) throws SQLException {
				while (re.next()) {
					QbdzEntity x = new QbdzEntity();
					x.id = re.getInt(1);
					x.tblj = re.getString(2);
					x.ywm_m = re.getString(3);
					x.zwm_m = re.getString(4);
					x.ywm_s = re.getString(5);
					x.zwm_s = re.getString(6);
					x.scid = re.getInt(7);
					if (list == null) {
						list = new ArrayList<>();
					}
					list.add(x);
				}
				return list == null ? null : list.toArray(new QbdzEntity[list.size()]);
			}
		}, sql.toString());
	}

	@Override
	public String getTb(int bid) throws Throwable {
		String url = "";
		StringBuffer s = new StringBuffer("SELECT F05 FROM T6013 WHERE  F01>0");
		if (bid > 0) {
			s.append(" AND F01=? ORDER BY F01 ASC LIMIT 1");
			url = selectString(P2PConst.DB_USER, s.toString(), bid);
		} else {
			s.append(" ORDER BY F01 ASC LIMIT 1");
			url = selectString(P2PConst.DB_USER, s.toString());
		}
		return url;
	}

	@Override
	public String getTbZrzc(int bid, int type) throws Throwable {
		String url = "";
		int count = selectInt(P2PConst.DB_USER, "SELECT COUNT(F01) FROM T6013 WHERE F01=? AND F06=?", bid, IsPass.F);
		if (count > 0) {
			bid = 0;
		}
		StringBuffer s = new StringBuffer("SELECT F05 FROM T6013 WHERE  F01>0");
		if (bid > 0) {
			s.append(" AND F01=? ");
			if (type == 1) {
				s.append(" AND F06='S'");
			}
			if (type == 2) {
				s.append(" AND F07='S'");
			}
			s.append(" ORDER BY F01 ASC LIMIT 1");
			url = selectString(P2PConst.DB_USER, s.toString(), bid);
		} else {
			if (type == 1) {
				s.append(" AND F06='S'");
			}
			if (type == 2) {
				s.append(" AND F07='S'");
			}
			s.append(" ORDER BY F01 ASC LIMIT 1");

			url = selectString(P2PConst.DB_USER, s.toString());
		}
		return url;
	}

	public String getTbsc(int fqid) throws Throwable {
		String url = "";
		StringBuffer s = new StringBuffer(
				"SELECT T6013.F05 FROM T6015 LEFT JOIN T6013 ON T6015.F04=T6013.F01 WHERE  T6013.F01>0");
		if (fqid > 0) {
			s.append(" AND T6015.F01=? ORDER BY T6015.F01 ASC LIMIT 1");
			url = selectString(P2PConst.DB_USER, s.toString(), fqid);
		} else {
			s.append(" ORDER BY T6015.F01 ASC LIMIT 1");
			url = selectString(P2PConst.DB_USER, s.toString());
		}
		return url;
	}

	@Override
	public void addQbdz(String bq, int bid, String qbdz, String jymm) throws Throwable {
		if (bid <= 0) {
			throw new ParameterException("err_1061");
		}
		if (StringHelper.isEmpty(qbdz)) {
			throw new ParameterException("err_1062");
		}
		if (!Jymm(jymm)) {
			throw new ParameterException("err_1029");
		}
		int id = selectInt(P2PConst.DB_USER, "SELECT F01 FROM T6012 WHERE F02=? AND F03=? AND F05=? AND F06=?",
				serviceResource.getSession().getAccountId(), bid, qbdz, IsPass.F);
		if (id > 0) {
			execute(getConnection(P2PConst.DB_USER), "UPDATE T6012 SET F06=?,F07=CURRENT_TIMESTAMP() WHERE F01=?",
					IsPass.S, id);
		} else {
			execute(getConnection(P2PConst.DB_USER),
					"INSERT INTO T6012 SET F02=?,F03=?,F04=?,F05=?,F07=CURRENT_TIMESTAMP()",
					serviceResource.getSession().getAccountId(), bid, bq, qbdz);
		}

	}

	@Override
	public QbdzEntity[] qbdzList(int bid) throws Throwable {
		ArrayList<Object> parameters = new ArrayList<Object>();
		StringBuffer s = new StringBuffer(
				"SELECT T6012.F01 id,T6013.F03 ywm,T6013.F04 zwm,T6012.F04 bq,T6012.F05 qbdz,T6012.F07 sj,T6013.F05 tblj ");
		s.append(" FROM T6012 LEFT JOIN T6013 ON T6012.F03=T6013.F01 WHERE 1=1");
		s.append(" AND T6012.F03=? AND T6012.F02=?");
		if (bid <= 0) {
			bid = getBid();
		}
		parameters.add(bid);
		parameters.add(serviceResource.getSession().getAccountId());
		s.append(" AND T6012.F06=?");
		parameters.add(IsPass.S);
		s.append(" ORDER BY T6012.F06 DESC");
		return selectAll(getConnection(P2PConst.DB_USER), new ArrayParser<QbdzEntity>() {
			ArrayList<QbdzEntity> list = new ArrayList<QbdzEntity>();

			@Override
			public QbdzEntity[] parse(ResultSet re) throws SQLException {
				while (re.next()) {
					QbdzEntity b = new QbdzEntity();
					b.id = re.getInt(1);
					b.ywjc = re.getString(2);
					b.zwm = re.getString(3);
					b.bq = re.getString(4);
					b.dz = re.getString(5);
					b.sj = re.getTimestamp(6);
					b.tblj = re.getString(7);
					list.add(b);
				}
				return list == null || list.size() == 0 ? null : list.toArray(new QbdzEntity[list.size()]);
			}
		}, s.toString(), parameters);
	}

	@Override
	public void deleteQbdz(int id) throws Throwable {
		if (id <= 0) {
			throw new ParameterException("err_1063");
		}
		execute(getConnection(P2PConst.DB_USER), "UPDATE T6012 SET F06=? WHERE F01=?", IsPass.F, id);
	}

	@Override
	public void add(PartFile z, PartFile f) throws Throwable {
		if (z == null) {
			throw new ParameterException("err_1064");
		}
		if (f == null) {
			throw new ParameterException("err_1065");
		}
		// FileStore fileStore = serviceResource.getResource(FileStore.class);
		// String imageCode1 =
		// fileStore.upload(FileType.CERTIFICATE_IMAGE.ordinal(), z)[0];
		// String imageCode2 =
		// fileStore.upload(FileType.CERTIFICATE_IMAGE.ordinal(), f)[0];
		execute(getConnection(P2PConst.DB_USER),
				"INSERT INTO T6011_1 SET F01=?,F02=?,F03=? ON DUPLICATE KEY UPDATE F02=?,F03=?",
				serviceResource.getSession().getAccountId(), z.getInputStream(), f.getInputStream(), z.getInputStream(),
				f.getInputStream());
		execute(getConnection(P2PConst.DB_USER), "UPDATE T6011 SET F13=? WHERE F01=?", null,
				serviceResource.getSession().getAccountId());
	}

	@Override
	public int getZp() throws Throwable {
		return selectInt(P2PConst.DB_USER, "SELECT COUNT(F01) FROM T6011_1 WHERE F01=?",
				serviceResource.getSession().getAccountId());
	}

	@Override
	public String getYy() throws Throwable {
		return selectString(P2PConst.DB_USER, "SELECT F04 FROM T6011_1 WHERE F01=?",
				serviceResource.getSession().getAccountId());
	}

	private int getBid() throws SQLException {
		return selectInt(P2PConst.DB_USER, "SELECT F01 FROM T6013 WHERE F01>0 ORDER BY T6013.F01 ASC");
	}

	@Override
	public void updateJymm(String password, int userId) throws Throwable {
		if (StringHelper.isEmpty(password)) {
			throw new ParameterException("err_1000");
		}
		if (userId <= 0) {
			throw new ParameterException("err_1001");
		}
		String dlmm = selectString(P2PConst.DB_USER, "SELECT F03 FROM T6010 WHERE F01=?",
				serviceResource.getSession().getAccountId());
		if (dlmm.equals(UnixCrypt.crypt(password, DigestUtils.sha256Hex(password)))) {
			throw new ParameterException("err_1002");
		}
		execute(getConnection(FrontConst.DB_USER), "UPDATE T6011 SET F11=? WHERE F01=?", UnixCrypt.crypt(password, DigestUtils.sha256Hex(password)),userId);

	}

	@Override
	public boolean updateBankCard(int id, String sql,Object... params) throws Throwable {
		if(id<=0||null==sql) return false;
		try {
			execute(getConnection(P2PConst.DB_USER), sql, params);
		} catch (Exception e) {			
			e.printStackTrace();
			return false;
		}
		return true;
	}

}